#ifndef MESSAGE_H_INCLUDED
#define MESSAGE_H_INCLUDED

#include <string>

namespace Core {

/** Base message structure
 *
 */
struct IMessage {
	const int m_messageType;
	
	explicit IMessage(int type) : m_messageType(type) { }
	int type() { return m_messageType; }
	
};

/** Message types */
enum MessageType {
	EProgressMessage = 1,
	EGuidFoundMessage = 2,
	ENotFoundMessage = 3,
	EErrorMessage = 4,
        EInterruptedMessage = 5
};

/** Progress notification message
 *
 */
struct ProgressMessage	: public IMessage
{
        float m_progressValue;

	ProgressMessage(float progressValue) : IMessage (EProgressMessage), m_progressValue(progressValue) { }
	
	static int const type = EProgressMessage;
	
};

/** Message is occurred when hashString was found
 *
 */
struct GUIDFoundMessage	: public IMessage{
	const std::string m_guid;
	
	GUIDFoundMessage(const std::string & guid) : IMessage (EGuidFoundMessage), m_guid(guid) { }
	
	static int const type = EGuidFoundMessage;
};


/** Message is occurred when hashString was not found
 *
 */
struct NotFoundMessage	: public IMessage {
	NotFoundMessage() : IMessage (ENotFoundMessage) { }
	
	static int const type = ENotFoundMessage;
};

/** Message is occurred when error is occurred
 *
 */
struct ErrorMessage	: public IMessage {
	const std::string m_errorMessage;
	const int m_errorCode;
	
	ErrorMessage(int errorCode, const std::string & errorMessage) 	: IMessage (EErrorMessage),
                                                                          m_errorMessage(errorMessage),
                                                                          m_errorCode(errorCode)
        { }

	static int const type = EErrorMessage;
}; 

/** Message is occurred if algorithm was interrupted
 *
 */
struct InterruptedMessage	: public IMessage {
	InterruptedMessage() : IMessage (EInterruptedMessage) { }
	
	static int const type = EInterruptedMessage;
};

template<typename T>
T *messageCast(IMessage *msg)
{
    if (msg->type() == T::type)
        return static_cast<T*>(msg);

    return NULL;
}


} // namespace Core



#endif
